//**************************************************************//
//  verify.cpp
//
//  - implements functions to verify a X509 file vs a CA cert
//
//**************************************************************//

#include "openssl/x509.h"
#include "openssl/x509v3.h"
#include "openssl/x509_vfy.h"
#include "openssl/pem.h"
#include "openssl/err.h"
#include "openssl/rand.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>

#define CA_DIR "realkeys"
#define CAFile "realkeys/root.pem"

int vcallback(int ok, X509_STORE_CTX* store)
{
  return ok;
}

bool VerifyCertificate(X509* certToVerify, const char* commonName)
{
  X509_STORE* store;
  X509_STORE_CTX* verify_ctx;
  bool certValid = false;
  char cert_CN[256];

  OpenSSL_add_all_algorithms();
  ERR_load_CRYPTO_strings();
  //seed_prng();

  if (!(store = X509_STORE_new()))
      printf("Error creating X509 store\n");

  X509_STORE_set_verify_cb_func(store, vcallback);

  if (X509_STORE_load_locations(store, CAFile, CA_DIR) != 1)
      printf("Error loading CAFile\n");

  if (!(verify_ctx = X509_STORE_CTX_new()))
      printf("Error creating X509 store ctx\n");

#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
  if (X509_STORE_CTX_init(verify_ctx, store, certToVerify, NULL) != 1)
      printf("Error init CTX\n");
#else
  X509_STORE_CTX_init(verify_ctx, store, cert, NULL);
#endif

  certValid = (X509_verify_cert(verify_ctx) == 1);

  X509_NAME_get_text_by_NID(X509_get_subject_name(certToVerify), NID_commonName, cert_CN, 256);
  X509_STORE_free(store);
  X509_STORE_CTX_free(verify_ctx);
  return ((certValid == true) && (strcasecmp(cert_CN, commonName) == 0));
}
